package simpleGui;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import processing.core.PApplet;
import processing.core.PGraphics;

public class PCamera3D implements MouseListener, MouseMotionListener {
	PApplet parent;
	PGraphics g3d;
	public boolean active=true;
	public boolean auto=false;
	float mouseXi, mouseYi;
	int gX;// xposition of the graphics
	int gY;// yposition of the graphics
	public float scale=400;
	public float initScale=400;
	public float scaleT;
	public float minScale=50;
	public float transX;
	public float transXT;
	public float transY;
	public float transYT;
	public float rotX;
	public float rotXT;
	public float rotY;
	public float rotYT;
	

	public PCamera3D(PApplet parent) {
		this(parent,0,0,200);
	}
	public PCamera3D(PApplet parent,float initScale) {
		this(parent,0,0,initScale);
	}
	public PCamera3D(PApplet parent,float initScale,float minScale) {
		this(parent,0,0,initScale);
		this.minScale=minScale;
	}
	public PCamera3D(PApplet parent,int graphicX,int graphicY,float initScale) {
		this.parent = parent;
		this.gX=graphicX;
		this.gY=graphicY;
		this.initScale=initScale;
		reset();
		parent.addMouseListener(this);
		parent.addMouseMotionListener(this);
		parent.registerMethod("mouseEvent",this);
		parent.registerPre(this);
		
	}
	public PCamera3D(PApplet parent,PGraphics g,int graphicX,int graphicY) {
		this( parent, graphicX, graphicY,300);
		this.g3d=g;
	}
	
	public void  doTransform(){
		transX = transX + transXT;
		transXT = 0;
		transY = transY + transYT;
		transYT = 0;
		scale = scale + scaleT;
		scaleT = 0;
		scale = parent.max(minScale, scale);
		rotX = rotX + rotXT;
		rotXT = 0;
		rotY = rotY + rotYT;
		rotYT = 0;
	}
	public void apply(PGraphics g3d){
		g3d.translate(g3d.width/2, g3d.height/2);
		g3d.translate(transX,transY);
		g3d.scale(scale);
		g3d.rotateX(rotX/500);
		g3d.rotateY(rotY/500);
	}
	
	public void pre(){
		if (active){
			doTransform();
		}
		if (auto){
		if (g3d==null){
			apply(parent.g);
		}
		else{
			apply(g3d);
		}
		}
		
	}
	public void reset(){
		transX=0;
		transY=0;
		rotX=0;
		rotY=0;
		scale=initScale;
	}
	public void mouseEvent(final processing.event.MouseEvent m){
		//
		if (m.getAction()==processing.event.MouseEvent.PRESS){
			mousePressed(null);
		}
		else if (m.getAction()==processing.event.MouseEvent.DRAG){
			MouseEvent javaMouse=new MouseEvent(parent, 0, 0, m.getModifiers(), m.getX(),  m.getY(), m.getCount(), false);
			mouseDragged(javaMouse);
		}
		else if (m.getAction()==processing.event.MouseEvent.CLICK){
			MouseEvent javaMouse=new MouseEvent(parent, 0, 0, m.getModifiers(), m.getX(),  m.getY(), m.getCount(), false);
			mouseClicked(javaMouse);
		}
	}
	
	public void mousePressed(MouseEvent e) {
		mouseXi = parent.mouseX-gX;
		mouseYi = parent.mouseY-gY;
	}

	public void mouseDragged(MouseEvent arg0) {
		// TODO Auto-generated method stub
		int mouseX = parent.mouseX-gX;
		int mouseY = parent.mouseY-gY;
		
		//if (parent.mouseButton == PApplet.RIGHT) {
		if (arg0.isAltDown()) {
			scaleT = (mouseX - mouseXi + mouseYi - mouseY) * 2;
			//scaleT = parent.max(minScale, scaleT);
		}
			else{
		if (parent.mouseButton == PApplet.CENTER) {
			transXT = (parent.mouseX - mouseXi);
			transYT = (mouseY - mouseYi);
		}
		if (parent.mouseButton == PApplet.LEFT) {
			rotYT = -(mouseX - mouseXi);
			rotXT = -(mouseY - mouseYi);
		}
			}
	}

	public void mouseReleased(MouseEvent event) {
	}

	public void mouseMoved(MouseEvent arg0) {
		// TODO Auto-generated method stub
	}

	public void mouseClicked(MouseEvent arg0) {
		if (arg0.getClickCount()>1){
			reset();
		}
		// TODO Auto-generated method stub
	}

	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
	}

	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
	}
	public boolean isActive() {
		return active;
	}
	public void setActive(boolean active) {
		this.active = active;
	}
	public static void  drawWorldAxis3D(PGraphics pg,float scale){
		pg.pushStyle();
		pg.stroke(255,0,0);
		pg.line(0,0,0,scale,0,0);
		pg.stroke(0,255,0);
		pg.line(0,0,0,0,scale,0);
		pg.stroke(0,0,255);
		pg.line(0,0,0,0,0,scale);
		pg.popStyle();
	}
	
	
}
